<script setup>
import { reactive, ref, computed  } from "vue";
import { uploadFile } from "@/api/common/file"
import { Delete, Edit, RefreshRight, Search, View, Plus } from "@element-plus/icons-vue";
import moment from 'moment'
import { MdEditor } from 'md-editor-v3'
import { UploadFilled } from '@element-plus/icons-vue'
import { findCoursePageList, addCourse, updateCourse, deleteCourse, selectById } from "@/api/blogger/course.js"
import { findAllCategory, findAllTagByCategoryId } from "@/api/common/common.js"
import { showMessage, showModel } from "@/composables/util.js";
import { useRouter } from 'vue-router'
import { Check, Close } from '@element-plus/icons-vue'
import 'md-editor-v3/lib/style.css'

// 定义响应式的表单对象
const form = reactive({
  title: '',
  type: '0',
  startDate: '',
  endDate: ''
})
// 监听日期组件改变事件，并将开始结束时间设置到变量中
const datepickerChange = (e) => {
  form.startDate = moment(e[0]).format('YYYY-MM-DD HH:mm:ss')
  form.endDate = moment(e[1]).format('YYYY-MM-DD HH:mm:ss')
  console.log('开始时间：' + form.startDate + ', 结束时间：' + form.endDate)
}

const shortcuts = [
  {
    text: '最近一周',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    },
  },
  {
    text: '最近一个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
    },
  },
  {
    text: '最近三个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
      return [start, end]
    },
  },
]

const pickDate = ref('')

// 表单引用
const searchForm = ref(null)

// 重置查询条件
const reset = () => {
  form.title = ''
  form.startDate = ''
  form.endDate = ''
  pickDate.value = ''
}

// 文章分类获取
const categories = ref([])
findAllCategory().then((res) => {
  console.log('获取分类数据：' + JSON.stringify(res.data.data))
  categories.value = res.data.data
})

// 文章分类获取
const tags = ref([])
// 获取对应分类的标签数据
function getTags(id) {
  console.log("进入获取对应分类的标签数据"+id)
  // 调用后台分页接口，并传入所需参数
  findAllTagByCategoryId({ id: id })
    .then((res) => {
      if (res.data.success == true) {
        console.log("对应标签数据：" + JSON.stringify(res.data.data))
        tags.value = res.data.data
      }
    })

}
// 控制dialog对话框显示情况
const summaryDialogVisible = ref(false)
// 课程数据
const courseList = ref([])
// 当前页码，初值默认为1
const current = ref(1)
// 总记录数，初值默认为0
const total = ref(0)
// 每页显示的记录数，初值默认为10
const size = ref(10)
const show = reactive({
  type: 0,
})
// 从浏览器本地存储中取出用户信息
let userInfo = JSON.parse(localStorage.getItem("userInfo"))
// 获取分页数据
function getCoursePageList() {
  // 调用后台分页接口，并传入所需参数
  findCoursePageList({ current: current.value, size: size.value, title: form.title, startDate: form.startDate, endDate: form.endDate, userId: userInfo.id, type: form.type })
    .then((res) => {
      if (res.data.success == true) {
        console.log("课程数据" + JSON.stringify(res.data.data))
        courseList.value = res.data.data
        current.value = res.data.current
        size.value = res.data.size
        total.value = res.data.total
        show.type = res.data.data[0].type
      }
    })
}
getCoursePageList()
// 课程类型
const type = ref(1)
// 对话框记录的课程介绍内容
const summary = ref('')
// 是否显示新增图文课程对话框
const isArticlePublishEditorShow = ref(false)
// 新增图文课程表单引用
const publishArticleFormRef = ref(null)
// 是否显示修改图文课程对话框
const isArticleUpdateEditorShow = ref(false)
// 修改图文课程表单引用
const updateArticleFormRef = ref(null)
// 是否显示新增视频课程对话框
const isVideoPublishEditorShow = ref(false)
// 新增视频课程表单引用
const publishVideoFormRef = ref(null)
// 是否显示修改视频课程对话框
const isVideoUpdateEditorShow = ref(false)
// 修改视频课程表单引用
const updateVideoFormRef = ref(null)

// 新增图文课程表单对象
const addArticleForm = reactive({
  title: '',
  cover: '',
  summary: "",
  contentOrLocation: '请输入内容',
  type: 0,
  price: null,
  userId: null,
  status: null,
  categoryId: null,
  tagId: null
})
// 修改图文课程表单
const updateArticleForm = reactive({
  title: '',
  cover: '',
  summary: "",
  contentOrLocation: '请输入内容',
  type: 0,
  price: null,
  userId: null,
  status: null,
  categoryId: null,
  tagId: null
})
// 新增视频课程表单对象
const addVideoForm = reactive({
  title: '',
  cover: '',
  summary: "",
  contentOrLocation: null,
  type: 1,
  price: null,
  userId: null,
  status: null,
  categoryId: null,
  tagId: null
})
// 修改视频课程表单
const updateVideoForm = reactive({
  title: '',
  cover: '',
  summary: "",
  contentOrLocation: null,
  type: 1,
  price: null,
  userId: null,
  status: null,
  categoryId: null,
  tagId: null
})


const progress = ref(0);

const upload = (file) => {
  const formData = new FormData();
  formData.append('file', file.raw);
  // 调用后台文件上传接口
  uploadFile(formData).then((res) => {
    // 响参失败，提示错误消息
    if (res.data.success == false) {
      let message = res.data.message
      showMessage(message, 'error')
      return
    }
    addVideoForm.contentOrLocation = res.data.data
  })
};

// 上传文章封面图片
const handleArticleCoverChange = (file) => {
  // 表单对象
  let formData = new FormData()
  // 添加 file 字段，并将文件传入 
  formData.append('file', file.raw)
  uploadFile(formData).then((res) => {
    // 响参失败，提示错误消息
    if (res.data.success == false) {
      let message = res.data.message
      showMessage(message, 'error')
      return
    }
    console.log("图片路径："+res.data.data)
    // 成功则设置表单对象中的封面链接，并提示上传成功
    addArticleForm.cover = res.data.data
    showMessage('上传成功')
  })
}

// 上传视频封面图片
const handleVideoCoverChange = (file) => {
  // 表单对象
  let formData = new FormData()
  // 添加 file 字段，并将文件传入 
  formData.append('file', file.raw)
  uploadFile(formData).then((res) => {
    // 响参失败，提示错误消息
    if (res.data.success == false) {
      let message = res.data.message
      showMessage(message, 'error')
      return
    }
    // 成功则设置表单对象中的封面链接，并提示上传成功
    addVideoForm.cover = res.data.data
    showMessage('上传成功')
  })
}

// 上传文章封面图片
const handleArticleCoverChangeUpdate = (file) => {
  // 表单对象
  let formData = new FormData()
  // 添加 file 字段，并将文件传入 
  formData.append('file', file.raw)
  uploadFile(formData).then((res) => {
    // 响参失败，提示错误消息
    if (res.data.success == false) {
      let message = res.data.message
      showMessage(message, 'error')
      return
    }
    console.log("图片路径："+res.data.data)
    // 成功则设置表单对象中的封面链接，并提示上传成功
    updateArticleForm.cover = res.data.data
    showMessage('上传成功')
  })
}

// 上传视频封面图片
const handleVideoCoverChangeUpdate = (file) => {
  // 表单对象
  let formData = new FormData()
  // 添加 file 字段，并将文件传入 
  formData.append('file', file.raw)
  uploadFile(formData).then((res) => {
    // 响参失败，提示错误消息
    if (res.data.success == false) {
      let message = res.data.message
      showMessage(message, 'error')
      return
    }
    // 成功则设置表单对象中的封面链接，并提示上传成功
    updateVideoForm.cover = res.data.data
    showMessage('上传成功')
  })
}

const handleProgress = event => {
  progress.value = event.percent;
};

const handleSuccess = () => {
  progress.value = 0;
  // 显示成功消息
  console.log('上传成功');
};

const handleError = () => {
  progress.value = 0;
  // 显示错误消息
  console.error('上传失败');
};

// 表单校验规则
const rules = {
  title: [
    { required: true, message: '请输入课程标题', trigger: 'blur' },
    { min: 1, max: 40, message: '课程标题要求大于1个字符，小于40个字符', trigger: 'blur' },
  ],
  contentOrLocation: [{ required: true }],
  price: [{ required: true, message: '请输入课程价格', trigger: 'blur' }],
  cover: [{ required: true }],
  categoryId: [{ required: true, message: '请选择课程分类', trigger: 'blur' }],
  tagId: [{ required: true, message: '请选择课程标签', trigger: 'blur' }],
}


// 发布文章
const articleAddSubmit = (status) => {
  // 校验表单
  publishArticleFormRef.value.validate((valid) => {
    if (!valid) {
      return false
    }
    addArticleForm.status = status
    addArticleForm.userId = userInfo.id
    addCourse(addArticleForm).then((res) => {
      if (res.data.success == false) {
        // 获取服务端返回的错误消息
        let message = res.data.message
        // 提示错误消息
        showMessage(message, 'error')
        return
      }
      if (status === 0) {
        showMessage('暂存成功')
      } else {
        showMessage('发布成功')
      }
      // 隐藏发布文章对话框
      isArticlePublishEditorShow.value = false
      // 表单字段置空
      addArticleForm.title = ''
      addArticleForm.contentOrLocation = ''
      addArticleForm.cover = ''
      addArticleForm.summary = ''
      addArticleForm.userId = userInfo.id
      addArticleForm.status = status
      addArticleForm.price = null
      addArticleForm.categoryId = null
      addArticleForm.tagId = null
      // 重新请求分页接口，渲染列表数据
      getCoursePageList()
    })
  })
}

// 修改课程信息
const articleUpdateSubmit = (status) => {
  updateArticleForm.status = status
  // 调用后端修改分类接口
  updateCourse(updateArticleForm).then((res) => {
    if (res.data.success === true) {
      // 提示修改成功
      if (status === 0) {
        showMessage('修改成功')
      } else {
        showMessage('发布成功')
      }
      isArticleUpdateEditorShow.value = false
      getCoursePageList()
    } else {
      let message = res.data.message
      console.log(message)
      // 提示消息
      showMessage(message, 'error')
    }
  })
}

// 发布视频
const videoAddSubmit = (status) => {
  console.log("进入发布视频submit")
  // 校验表单
  publishVideoFormRef.value.validate((valid) => {
    if (!valid) {
      return false
    }
    addVideoForm.status = status
    addVideoForm.userId = userInfo.id
    addCourse(addVideoForm).then((res) => {
      if (res.data.success == false) {
        // 获取服务端返回的错误消息
        let message = res.data.message
        // 提示错误消息
        showMessage(message, 'error')
        return
      }
      if (status === 0) {
        showMessage('暂存成功')
      } else {
        showMessage('发布成功')
      }
      // 隐藏发布文章对话框
      isVideoPublishEditorShow.value = false
      // 表单字段置空
      addVideoForm.title = ''
      addVideoForm.contentOrLocation = ''
      addVideoForm.cover = ''
      addVideoForm.summary = ''
      addVideoForm.userId = userInfo.id
      addVideoForm.status = status
      addVideoForm.price = null
      addVideoForm.categoryId = null
      addVideoForm.tagId = null
      window.location.reload()
    })
  })
}

// 修改课程信息
const videoUpdateSubmit = (status) => {
  updateVideoForm.status = status
  // 调用后端修改分类接口
  updateCourse(updateVideoForm).then((res) => {
    if (res.data.success === true) {
      // 提示修改成功
      if (status === 0) {
        showMessage('修改成功')
      } else {
        showMessage('发布成功')
      }
      isVideoUpdateEditorShow.value = false
      getCoursePageList()
    } else {
      let message = res.data.message
      console.log(message)
      // 提示消息
      showMessage(message, 'error')
    }
  })
}
// 返回文章详情
const selectOneArticle = (id, type) => {
  isArticleUpdateEditorShow.value = true
  selectById({id: id, type: type}).then((res) => {
    if (res.data.success === true) {
      // 把对应分类标签数据也查出来
      getTags(res.data.data.categoryId)
      console.log(res.data.data)
      updateArticleForm.id = res.data.data.id
      updateArticleForm.title = res.data.data.title
      updateArticleForm.contentOrLocation = res.data.data.contentOrLocation
      updateArticleForm.cover = res.data.data.cover
      updateArticleForm.summary = res.data.data.summary
      updateArticleForm.userId = res.data.data.userId
      updateArticleForm.status = res.data.data.status
      updateArticleForm.price = res.data.data.price
      updateArticleForm.categoryId = res.data.data.categoryId
      updateArticleForm.tagId = res.data.data.tagId
    } else {
      let message = res.data.message
      console.log(message)
      // 提示消息
      showMessage(message, 'error')
    }
  })
}
// 返回视频详情
const selectOneVideo = (id, type) => {
  isVideoUpdateEditorShow.value = true
  selectById({id: id, type: type}).then((res) => {
    if (res.data.success === true) {
      // 把对应分类标签数据也查出来
      getTags(res.data.data.categoryId)
      console.log(res.data.data)
      updateVideoForm.id = res.data.data.id
      updateVideoForm.title = res.data.data.title
      updateVideoForm.contentOrLocation = res.data.data.contentOrLocation
      updateVideoForm.cover = res.data.data.cover
      updateVideoForm.summary = res.data.data.summary
      updateVideoForm.userId = res.data.data.userId
      updateVideoForm.status = res.data.data.status
      updateVideoForm.price = res.data.data.price
      updateVideoForm.categoryId = res.data.data.categoryId
      updateVideoForm.tagId = res.data.data.tagId
    } else {
      let message = res.data.message
      console.log(message)
      // 提示消息
      showMessage(message, 'error')
    }
  })
}

//删除课程
const deleteSubmit = (id, type, status) => {
    showModel('是否删除该课程?').then(() => {
        deleteCourse({id: id, type: type, status: status}).then((res) => {
            if (res.data.success == true) {
                showMessage('删除成功')
                // 重新请求分页接口，渲染数据
                getCoursePageList()
            } else {
                // 获取服务端返回的错误消息
                let message = res.data.message
                // 提示错误消息
                showMessage(message, 'error')
            }
        })
    }).catch(() => {
        console.log('取消了')
    })
}

// 存储选中项的ID数组
const selectedIds = ref([]);
const handleSelectionChange = (selection) => {
  selectedIds.value = selection.map(item => item.id);
  console.log(selectedIds)
};

function handleIndex(index) {
  // 假设分页参数为 current（当前页）和 size（每页条数）
  return (current.value - 1) * size.value + index + 1;
}

// 状态管理
const previewUrl = ref('')
const uploadProgress = ref(0)
const uploadStatus = reactive({
  uploading: false,
  error: false,
  fileName: '',
  fileSize: 0
})

// 重置视频上传状态
const resetVideoUploadState = () => {
  previewUrl.value = ''
  uploadProgress.value = 0
  uploadStatus.uploading = false
  uploadStatus.error = false
  uploadStatus.fileName = ''
  uploadStatus.fileSize = 0
}

// 格式化文件大小
const fileSizeFormatted = computed(() => {
  const sizeMB = uploadStatus.fileSize / 1024 / 1024
  return sizeMB.toFixed(2) + 'MB'
})

// 文件选择处理
const handleFileChange = (file) => {
  if (!file) return
  
  // 生成预览
  previewUrl.value = URL.createObjectURL(file.raw)
  
  // 记录文件信息
  uploadStatus.fileName = file.name
  uploadStatus.fileSize = file.size
  uploadStatus.uploading = true
  uploadStatus.error = false
  uploadProgress.value = 0

  const formData = new FormData();
  formData.append('file', file.raw);
  
  // 调用后台文件上传接口，传入进度回调
  uploadFile(formData, (progress) => {
    uploadProgress.value = progress;
  }).then((res) => {
    // 响参失败，提示错误消息
    if (res.data.success == false) {
      uploadStatus.error = true;
      let message = res.data.message;
      showMessage(message, 'error');
      return;
    }
    // 上传成功，设置URL并更新状态
    addVideoForm.contentOrLocation = res.data.data;
    updateVideoForm.contentOrLocation = res.data.data;
    uploadStatus.uploading = false;
    uploadProgress.value = 100;
  }).catch(error => {
    uploadStatus.error = true;
    uploadStatus.uploading = false;
    showMessage(error.message || '上传失败', 'error');
  });
}

// 上传前校验
const beforeUpload = (file) => {
  // 重置状态
  uploadProgress.value = 0
  uploadStatus.uploading = true
  uploadStatus.error = false

  // 文件类型校验
  if (!file.type.startsWith('video/')) {
    return false
  }

  // 文件大小限制（50MB）
  const maxSize = 500 * 1024 * 1024
  if (file.size > maxSize) {
    return false
  }

  return true
}

// 上传进度处理
const handleUploadProgress = (event) => {
  uploadProgress.value = Math.round((event.loaded / event.total) * 100)
}

// 视频预览相关的响应式变量
const videoPreviewVisible = ref(false)
const currentVideoUrl = ref('')

// 打开视频预览
const openVideoPreview = (row) => {
  if (row.type === 1 && row.contentOrLocation) { // 确保是视频课程且有视频地址
    currentVideoUrl.value = row.contentOrLocation
    videoPreviewVisible.value = true
  }
}

// 关闭视频预览
const handleCloseVideoPreview = () => {
  videoPreviewVisible.value = false
  currentVideoUrl.value = ''
}

</script>

<template>

  <!-- 查询表单 -->
  <el-form ref="searchForm" :model="form" style="
        margin:-10px 0 15px -10px;
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 12px 20px;
    " class="card" shadow="always" inline>
    <el-form-item prop="username" style="
            margin: 0;
            display: flex;
            align-items: center;
            gap: 8px;
        ">
      <el-text style="min-width: 60px; margin-right: 15px; text-align: center">课程标题</el-text>
      <el-input v-model="form.title" style="width: 220px" prefix-icon="Search" placeholder="请输入" />
    </el-form-item>

    <el-form-item prop="type" style="
            margin: 0;
            display: flex;
            align-items: center;
            gap: 8px;
        ">
      <el-select v-model="form.type" style="width: 140px">
        <el-option label="图文课程" value="0"></el-option>
        <el-option label="视频课程" value="1"></el-option>
      </el-select>
    </el-form-item>

    <el-form-item style="
            margin: 0;
            display: flex;
            align-items: center;
            gap: 8px;">
      <el-text style="min-width: 60px; margin-right: 15px; text-align: center">创建日期</el-text>
      <el-date-picker v-model="pickDate" type="daterange" range-separator="至" start-placeholder="开始时间"
        end-placeholder="结束时间" size="default" :shortcuts="shortcuts" style="width: 360px" @change="datepickerChange" />
    </el-form-item>

    <el-form-item style="margin-left: 10px; justify-content: center; padding-top: 14px">
      <el-button type="primary" plain :icon="Search" style="padding: 8px 20px;" @click="getCoursePageList()">
        查询
      </el-button>
      <el-button type="warning" plain :icon="RefreshRight" style="margin-left: 12px; padding: 8px 20px;" @click="reset">
        重置
      </el-button>
    </el-form-item>
  </el-form>

  <!--操作区-->
  <div style="margin:-10px 0 15px -10px" class="card" shadow="always">
    <el-button style="margin-left: 8px" type="success" plain
      @click="isArticlePublishEditorShow = true">新增图文课程</el-button>
    <el-button style="margin-left: 8px" type="success" plain 
      @click="isVideoPublishEditorShow = true">新增视频课程</el-button>
    <el-button type="danger" plain :icon="Delete" style="padding: 8px 20px;">批量删除</el-button>
  </div>

  <!--数据展示区-->
  <div style="margin:-10px 0 15px -10px" class="card" shadow="always">
    <el-table :data="courseList" style="width: 100%" @selection-change="handleSelectionChange" row-key="id">
      <el-table-column type="selection" :reserve-selection="true" width="55" />
      <el-table-column type="index" :index="handleIndex" label="序号" width="80px" />
      <el-table-column property="cover" label="课程封面" width="100px">
        <template #default="scope">
          <el-image style="width: 60px; height: 40px" :src="scope.row.cover" :zoom-rate="1.2" :max-scale="7"
            :min-scale="0.2" :preview-src-list="[scope.row.cover]" :initial-index="4" preview-teleported="true"
            fit="cover" />
        </template>
      </el-table-column>
      <el-table-column property="title" label="课程名称">
        <template #default="scope">
          <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
            <div class="text-overflow" style="width: 130px">{{ scope.row.title }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column property="summary" label="课程介绍">
        <template #default="scope">
          <el-button type="success" @click="summaryDialogVisible = true, summary = scope.row.summary">查看介绍</el-button>
        </template>
      </el-table-column>

      <el-table-column property="username" label="上传博主" />
      <el-table-column property="price" label="课程价格">
        <template #default="scope">
          {{ scope.row.price + '元' }}
        </template>
      </el-table-column>
      <el-table-column property="location" label="视频详情" v-if="show.type === 1">
        <template #default="scope">
          <el-button type="warning" @click="openVideoPreview(scope.row)">视频详情</el-button>
        </template>
      </el-table-column>
      <el-table-column property="status" label="审核状态">
        <template #default="scope">
          <span v-if="scope.row.status === 0">草稿</span>
          <span v-else-if="scope.row.status === 1">待审核</span>
          <span v-else-if="scope.row.status === 2">审核通过</span>
          <span v-else-if="scope.row.status === 3">审核不通过</span>
          <span v-else>被设为推荐</span>
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template #default="scope">
          <el-button style="margin-left: 8px" type="primary" plain :icon="Edit" circle v-if="scope.row.type === 0"
            @click="selectOneArticle(scope.row.id, scope.row.type)"></el-button>
            <el-button style="margin-left: 8px" type="primary" plain :icon="Edit" circle v-else
            @click="selectOneVideo(scope.row.id, scope.row.type)"></el-button>
          <el-button style="margin-left: 8px" type="danger" plain :icon="Delete" circle
            @click="deleteSubmit(scope.row.id, scope.row.type, scope.row.status)"></el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="demo-pagination-block">
      <el-pagination v-model:current-page="current" :page-size="[10, 20, 50]" :size="size" :disabled="disabled"
        background layout="total, prev, pager, next" :total="total" @size-change="handleSizeChange"
        @current-change="getCoursePageList" />
    </div>

    <!-- 新增图文课程  弹出对话框 -->
    <el-dialog v-model="isArticlePublishEditorShow" :width="1300" :show-close="false">
      <template #header="{ close, titleId, titleClass }">
        <!-- 固钉组件，固钉到顶部 -->
        <el-affix :offset="20" style="width: 100%;">
          <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
          <div>
            <!-- 字体加粗 -->
            <h4 class="font-bold">新增图文课程</h4>
            <!-- 靠右对齐 -->
            <div class="ml-auto flex" style="padding-left: 1030px;">
              <el-button @click="isArticlePublishEditorShow = false">取消</el-button>
              <el-button type="success" @click="articleAddSubmit(0)">
                <el-icon class="mr-1">
                  <Box />
                </el-icon>
                暂存
              </el-button>
              <el-button type="primary" @click="articleAddSubmit(1)">
                <el-icon class="mr-1">
                  <Promotion />
                </el-icon>
                发布
              </el-button>
            </div>
          </div>
        </el-affix>
      </template>

      <!-- label-position="top" 用于指定 label 元素在上面 -->
      <el-form :model="addArticleForm" ref="publishArticleFormRef" label-position="top" size="large" :rules="rules">
        <el-form-item label="标题" prop="title">
          <el-input v-model="addArticleForm.title" autocomplete="off" size="large" maxlength="40" show-word-limit
            clearable />
        </el-form-item>
        <el-form-item label="内容" prop="contentOrLocation">
          <!-- Markdown 编辑器 -->
          <MdEditor v-model="addArticleForm.contentOrLocation" @onUploadImg="onUploadImg"
            editorId="publishArticleEditor" />
        </el-form-item>
        <el-form-item label="封面" prop="cover">
          <el-upload class="avatar-uploader" action="#" :on-change="handleArticleCoverChange" :auto-upload="false"
            :show-file-list="false">
            <img v-if="addArticleForm.cover" :src="addArticleForm.cover" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="摘要" prop="summary">
          <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
          <el-input v-model="addArticleForm.summary" :rows="3" type="textarea" placeholder="文章摘要可以快速吸引读者眼球哦~" />
        </el-form-item>
        <el-form-item label="价格" prop="price">
          <el-input-number v-model="addArticleForm.price" :min="0">
            <template #suffix>
              <span>元</span>
            </template>
          </el-input-number>
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <el-select v-model="addArticleForm.categoryId" clearable placeholder="---请选择---" size="large"
            @change="getTags(addArticleForm.categoryId)">
            <el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签" prop="tagId">
          <el-select v-model="addArticleForm.tagId" clearable placeholder="---请选择---" size="large">
            <el-option v-for="item in tags" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 修改图文课程  弹出对话框 -->
    <el-dialog v-model="isArticleUpdateEditorShow" :width="1300" :show-close="false">
      <template #header="{ close, titleId, titleClass }">
        <!-- 固钉组件，固钉到顶部 -->
        <el-affix :offset="20" style="width: 100%;">
          <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
          <div>
            <!-- 字体加粗 -->
            <h4 class="font-bold">修改图文课程</h4>
            <!-- 靠右对齐 -->
            <div class="ml-auto flex" style="padding-left: 1030px;">
              <el-button @click="isArticleUpdateEditorShow = false">取消</el-button>
              <el-button type="success" @click="articleUpdateSubmit(0)">
                <el-icon class="mr-1">
                  <Box />
                </el-icon>
                暂存
              </el-button>
              <el-button type="primary" @click="articleUpdateSubmit(1)">
                <el-icon class="mr-1">
                  <Promotion />
                </el-icon>
                发布
              </el-button>
            </div>
          </div>
        </el-affix>
      </template>

      <!-- label-position="top" 用于指定 label 元素在上面 -->
      <el-form :model="updateArticleForm" ref="updateArticleFormRef" label-position="top" size="large" :rules="rules">
        <el-form-item label="标题" prop="title">
          <el-input v-model="updateArticleForm.title" autocomplete="off" size="large" maxlength="40" show-word-limit
            clearable />
        </el-form-item>
        <el-form-item label="内容" prop="contentOrLocation">
          <!-- Markdown 编辑器 -->
          <MdEditor v-model="updateArticleForm.contentOrLocation" @onUploadImg="onUploadImg"
            editorId="publishArticleEditor" />
        </el-form-item>
        <el-form-item label="封面" prop="cover">
          <el-upload class="avatar-uploader" action="#" :on-change="handleArticleCoverChangeUpdate" :auto-upload="false"
            :show-file-list="false">
            <img v-if="updateArticleForm.cover" :src="updateArticleForm.cover" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="摘要" prop="summary">
          <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
          <el-input v-model="updateArticleForm.summary" :rows="3" type="textarea" placeholder="文章摘要可以快速吸引读者眼球哦~" />
        </el-form-item>
        <el-form-item label="价格" prop="price">
          <el-input-number v-model="updateArticleForm.price" :min="0">
            <template #suffix>
              <span>元</span>
            </template>
          </el-input-number>
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <el-select v-model="updateArticleForm.categoryId" clearable placeholder="---请选择---" size="large"
            @change="getTags(updateArticleForm.categoryId)">
            <el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签" prop="tagId">
          <el-select v-model="updateArticleForm.tagId" clearable placeholder="---请选择---" size="large">
            <el-option v-for="item in tags" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 新增视频课程  弹出对话框 -->
    <el-dialog v-model="isVideoPublishEditorShow" :width="1300" :show-close="false" @closed="resetVideoUploadState">
      <template #header="{ close, titleId, titleClass }">
        <!-- 固钉组件，固钉到顶部 -->
        <el-affix :offset="20" style="width: 100%;">
          <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
          <div>
            <!-- 字体加粗 -->
            <h4 class="font-bold">新增视频课程</h4>
            <!-- 靠右对齐 -->
            <div class="ml-auto flex" style="padding-left: 1030px;">
              <el-button @click="isVideoPublishEditorShow = false">取消</el-button>
              <el-button type="success" @click="videoAddSubmit(0)">
                <el-icon class="mr-1">
                  <Box />
                </el-icon>
                暂存
              </el-button>
              <el-button type="primary" @click="videoAddSubmit(1)">
                <el-icon class="mr-1">
                  <Promotion />
                </el-icon>
                发布
              </el-button>
            </div>
          </div>
        </el-affix>
      </template>

      <!-- label-position="top" 用于指定 label 元素在上面 -->
      <el-form :model="addVideoForm" ref="publishVideoFormRef" label-position="top" size="large" :rules="rules">
        <el-form-item label="标题" prop="title">
          <el-input v-model="addVideoForm.title" autocomplete="off" size="large" maxlength="40" show-word-limit
            clearable />
        </el-form-item>
        <el-form-item label="封面" prop="cover">
          <el-upload class="avatar-uploader" action="#" :on-change="handleVideoCoverChange" :auto-upload="false"
            :show-file-list="false">
            <img v-if="addVideoForm.cover" :src="addVideoForm.cover" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="简介" prop="summary">
          <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
          <el-input v-model="addVideoForm.summary" :rows="3" type="textarea"
            placeholder="填写更全面的相关信息, 这样能让用户更能了解你的视频内容哦~" />
        </el-form-item>
        <el-form-item label="价格" prop="price">
          <el-input-number v-model="addVideoForm.price" :min="0">
            <template #suffix>
              <span>元</span>
            </template>
          </el-input-number>
        </el-form-item>
        <el-form-item label="视频" prop="cover">
          <div class="upload-container">
            <!-- 上传组件 -->
            <el-upload
              accept="video/*"
              :show-file-list="false"
              :before-upload="beforeUpload"
              :on-change="handleFileChange"
            >
              <el-button type="primary">
                {{ uploadStatus.uploading ? '上传中...' : '选择视频' }}
              </el-button>
            </el-upload>

            <!-- 视频预览 -->
            <div v-if="previewUrl" class="preview-wrapper">
              <video 
                :src="previewUrl"
                controls
                class="video-preview"
              ></video>
              <div class="video-info">
                文件名：{{ uploadStatus.fileName }}<br>
                大小：{{ fileSizeFormatted }}
              </div>
            </div>

            <!-- 上传进度 -->
            <div v-if="uploadStatus.uploading || uploadProgress === 100" class="progress-wrapper">
              <el-progress 
                :percentage="uploadProgress" 
                :status="uploadStatus.error ? 'exception' : uploadProgress === 100 ? 'success' : ''"
                stroke-width="8"
              />
              <div class="progress-text">
                {{ uploadProgress }}% 
                <span v-if="uploadStatus.error" class="error-text">上传失败</span>
                <span v-else-if="uploadProgress === 100" class="success-text">上传完成</span>
                <span v-else>上传中...</span>
              </div>
            </div>
          </div>
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <el-select v-model="addVideoForm.categoryId" clearable placeholder="---请选择---" size="large" @change="getTags(addVideoForm.categoryId)">
            <el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签" prop="tagId">
          <el-select v-model="addVideoForm.tagId" clearable placeholder="---请选择---" size="large">
            <el-option v-for="item in tags" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 修改视频课程  弹出对话框 -->
    <el-dialog v-model="isVideoUpdateEditorShow" :width="1300" :show-close="false" @closed="resetVideoUploadState">
      <template #header="{ close, titleId, titleClass }">
        <!-- 固钉组件，固钉到顶部 -->
        <el-affix :offset="20" style="width: 100%;">
          <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
          <div>
            <!-- 字体加粗 -->
            <h4 class="font-bold">修改视频课程</h4>
            <!-- 靠右对齐 -->
            <div class="ml-auto flex" style="padding-left: 1030px;">
              <el-button @click="isVideoUpdateEditorShow = false">取消</el-button>
              <el-button type="success" @click="videoUpdateSubmit(0)">
                <el-icon class="mr-1">
                  <Box />
                </el-icon>
                暂存
              </el-button>
              <el-button type="primary" @click="videoUpdateSubmit(1)">
                <el-icon class="mr-1">
                  <Promotion />
                </el-icon>
                发布
              </el-button>
            </div>
          </div>
        </el-affix>
      </template>

      <!-- label-position="top" 用于指定 label 元素在上面 -->
      <el-form :model="updateVideoForm" ref="updateVideoFormRef" label-position="top" size="large" :rules="rules">
        <el-form-item label="标题" prop="title">
          <el-input v-model="updateVideoForm.title" autocomplete="off" size="large" maxlength="40" show-word-limit
            clearable />
        </el-form-item>
        <el-form-item label="封面" prop="cover">
          <el-upload class="avatar-uploader" action="#" :on-change="handleVideoCoverChangeUpdate" :auto-upload="false"
            :show-file-list="false">
            <img v-if="updateVideoForm.cover" :src="updateVideoForm.cover" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="简介" prop="summary">
          <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
          <el-input v-model="updateVideoForm.summary" :rows="3" type="textarea"
            placeholder="填写更全面的相关信息, 这样能让用户更能了解你的视频内容哦~" />
        </el-form-item>
        <el-form-item label="价格" prop="price">
          <el-input-number v-model="updateVideoForm.price" :min="0">
            <template #suffix>
              <span>元</span>
            </template>
          </el-input-number>
        </el-form-item>
        <el-form-item label="视频" prop="cover">
          <div class="upload-container">
            <!-- 上传组件 -->
            <el-upload
              accept="video/*"
              :show-file-list="false"
              :before-upload="beforeUpload"
              :on-change="handleFileChange"
            >
              <el-button type="primary">
                {{ uploadStatus.uploading ? '上传中...' : '选择视频' }}
              </el-button>
            </el-upload>

            <!-- 视频预览 -->
            <div v-if="previewUrl" class="preview-wrapper">
              <video 
                :src="previewUrl"
                controls
                class="video-preview"
              ></video>
              <div class="video-info">
                文件名：{{ uploadStatus.fileName }}<br>
                大小：{{ fileSizeFormatted }}
              </div>
            </div>

            <!-- 上传进度 -->
            <div v-if="uploadStatus.uploading || uploadProgress === 100" class="progress-wrapper">
              <el-progress 
                :percentage="uploadProgress" 
                :status="uploadStatus.error ? 'exception' : uploadProgress === 100 ? 'success' : ''"
                stroke-width="8"
              />
              <div class="progress-text">
                {{ uploadProgress }}% 
                <span v-if="uploadStatus.error" class="error-text">上传失败</span>
                <span v-else-if="uploadProgress === 100" class="success-text">上传完成</span>
                <span v-else>上传中...</span>
              </div>
            </div>
          </div>
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <el-select v-model="updateVideoForm.categoryId" clearable placeholder="---请选择---" size="large" @change="getTags(updateVideoForm.categoryId)">
            <el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签" prop="tagId">
          <el-select v-model="updateVideoForm.tagId" clearable placeholder="---请选择---" size="large">
            <el-option v-for="item in tags" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
    </el-dialog>

    <el-dialog v-model="dialogVisible" :fullscreen="true" :show-close="false" custom-class="dispute-upload-dialog">
      <div class="center">
        <div class="fz-18 ellipsis">正在上传：{{ fileData.name }}</div>
        <el-progress :text-inside="true" :stroke-width="16" :percentage="percentage" />
        <el-button @click="cancel">取消上传</el-button>
      </div>
    </el-dialog>

    <!--要单独拿出来，否则会被循环重复渲染-->
    <el-dialog v-model="summaryDialogVisible" title="课程介绍" width="600" append-to-body="true">
      <span>{{ summary }}</span>
    </el-dialog>

    <!-- 视频预览对话框 -->
    <el-dialog
      v-model="videoPreviewVisible"
      title="视频预览"
      width="70%"
      :before-close="handleCloseVideoPreview"
      class="video-preview-dialog"
      destroy-on-close
    >
      <div class="video-container">
        <video
          v-if="currentVideoUrl"
          class="video-player"
          controls
          :src="currentVideoUrl"
          controlsList="nodownload"
          autoplay
        >
          您的浏览器不支持 HTML5 视频播放
        </video>
      </div>
    </el-dialog>

  </div>
</template>

<style scoped>
.upload-container {
  max-width: 600px;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid #eee;
  border-radius: 8px;
}

.preview-wrapper {
  margin-top: 20px;
}

.video-preview {
  width: 100%;
  border-radius: 6px;
  background: #000;
}

.video-info {
  margin-top: 10px;
  color: #666;
  font-size: 0.9em;
}

.progress-wrapper {
  margin-top: 20px;
}

.progress-text {
  text-align: center;
  margin-top: 8px;
  color: #666;
}

.error-text {
  color: #ff4d4f;
}

.success-text {
  color: #67C23A;
}

/* 封面图片样式 */
.avatar-uploader .avatar {
  width: 200px;
  height: 100px;
  display: block;
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 200px;
  height: 100px;
  text-align: center;
}

/* 指定 select 下拉框宽度 */
.el-select--large {
  width: 250px;
}

/* 视频预览对话框样式 */
.video-preview-dialog :deep(.el-dialog__body) {
  padding: 0;
}

.video-container {
  width: 100%;
  background-color: #000;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
}

.video-player {
  width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

/* 确保视频预览对话框在其他对话框之上 */
.video-preview-dialog {
  z-index: 3000;
}
</style>

<style>
.md-editor-footer {
  height: 40px;
}
</style>